package event

import (
	"fmt"
	"sync"
)

type Action func(data ...any)

type ActionChan struct {
	ActionId string
	Ac       Action
	Chan     chan []any
}

func (a *ActionChan) startListen() {
	go func() {
		for data := range a.Chan {
			a.Ac(data...)
		}
	}()
}

var (
	actions      map[string]map[string]ActionChan
	actionsMutex sync.Mutex
	idCounter    int
)

// 用法：event.Add(func(data event.Data) { })
func Add(eventName string, action Action) (actionId string) {
	if actions == nil {
		actions = make(map[string]map[string]ActionChan)
	}

	if _, exist := actions[eventName]; !exist {
		actions[eventName] = make(map[string]ActionChan)
	}
	actionMap := actions[eventName]

	actionId = generateID()
	actionChan := ActionChan{actionId, action, make(chan []any)}
	actionChan.startListen()
	actionMap[actionId] = actionChan

	actions[eventName] = actionMap
	return
}

func Remove(eventName string, actionId string) {
	if actions == nil {
		return
	}
	if ac, exist := actions[eventName]; exist {
		close(ac[actionId].Chan)
		delete(ac, actionId)
	}
}

func Emit(eventName string, data ...any) {
	if actions == nil {
		return
	}
	if ac, exist := actions[eventName]; exist {
		for _, actionChan := range ac {
			actionChan.Chan <- data
		}
	}
}

func generateID() string {
	actionsMutex.Lock()
	defer actionsMutex.Unlock()
	idCounter++
	return fmt.Sprintf("action-%d", idCounter)
}
